package com.liang.lingdong.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.liang.lingdong.common.ErrorCode;
import com.liang.lingdong.exception.BusinessException;
import com.liang.lingdong.model.exam.Exam;
import com.liang.lingdong.model.exam.dto.CreateExamDto;
import com.liang.lingdong.model.exam.dto.QueryExamListDto;
import com.liang.lingdong.model.exam.dto.UpdateExamDto;
import com.liang.lingdong.model.sign.Sign;
import com.liang.lingdong.model.user.User;
import com.liang.lingdong.service.ExamService;
import com.liang.lingdong.mapper.ExamMapper;
import com.liang.lingdong.service.SignService;
import com.liang.lingdong.service.UserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;


import javax.annotation.Resource;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

/**
* @author liang
* @description 针对表【exam(考试表)】的数据库操作Service实现
* @createDate 2024-11-29 21:34:17
*/
@Service
public class ExamServiceImpl extends ServiceImpl<ExamMapper, Exam>
    implements ExamService{

    @Resource
    private SignService signService;

    @Resource
    private UserService userService;

    /**
     * 创建考试
     * @param createExamDto 参数
     * @return 结果
     */
    @Override
    public Long createExam(CreateExamDto createExamDto) {
        String examName = createExamDto.getExamName();
        String examContent = createExamDto.getExamContent();
        Date startTime = createExamDto.getStartTime();
        Date endTime = createExamDto.getEndTime();
        Integer allowCuttingScreen = createExamDto.getAllowCuttingScreen();
        // 校验考试时间
        if (startTime.after(endTime)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"开始时间不能大于结束时间");
        }
        // 查询创建人
        Long loginId = (Long) StpUtil.getLoginId();
        // 创建考试
        Exam exam = Exam.builder()
                .examName(examName)
                .examContent(examContent)
                .startTime(startTime)
                .endTime(endTime)
                .createBy(loginId)
                .allowCuttingScreen(allowCuttingScreen)
                .createTime(new Date())
                .build();
        // 入库
        boolean save = this.save(exam);
        if (!save) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR);
        }
        return exam.getBusinessId();
    }


    /**
     * 更新考试
     * @param updateExamDto 参数
     * @return 结果
     */
    @Override
    public boolean updateExam(UpdateExamDto updateExamDto) {
        Long businessId = updateExamDto.getBusinessId();
        String examName = updateExamDto.getExamName();
        String examContent = updateExamDto.getExamContent();
        Date startTime = updateExamDto.getStartTime();
        Date endTime = updateExamDto.getEndTime();
        Integer allowCuttingScreen = updateExamDto.getAllowCuttingScreen();
        // 校验考试时间
        if (startTime.after(endTime)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"开始时间不能大于结束时间");
        }
        // 查询主键id
        Exam exam = this.getById(businessId);
        if (exam == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"考试不存在");
        }
        // 设置参数
        exam.setExamContent(examContent);
        exam.setExamName(examName);
        exam.setStartTime(startTime);
        exam.setEndTime(endTime);
        exam.setAllowCuttingScreen(allowCuttingScreen);
        // 更新
        boolean update = this.updateById(exam);
        if (!update) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR);
        }
        return true;
    }

    /**
     *  分页查询考试列表
     * @param queryExamListDto 查询参数
     * @return 结果
     */
    @Override
    public Page<Exam> getExamListByPage(QueryExamListDto queryExamListDto) {
        String examName = queryExamListDto.getExamName();
        long current = queryExamListDto.getCurrent();
        long pageSize = queryExamListDto.getPageSize();
        // 分页查询
        return this.lambdaQuery()
                .like(StringUtils.isNotBlank(examName), Exam::getExamName, examName)
                .page(new Page<>(current, pageSize));
    }

    /**
     * 获取我的考试列表
     * @return 结果
     */
    @Override
    public List<Exam> getMyExamListByPage() {
        // 获取登录用户
        Long loginId = (Long) StpUtil.getLoginId();
        // 查询用户报名的考试
        List<Sign> signList = signService.lambdaQuery()
                .eq(Sign::getUserId, loginId)
                .list();
        return this.lambdaQuery()
                .in(Exam::getBusinessId, signList)
                .list();
    }

    /**
     * 获取最新考试
     * @return 结果
     */
    @Override
    public Exam getLatestExam() {
        // 获取登录用户
        Long loginId = (Long) StpUtil.getLoginId();
        // 查询用户报名的考试
        List<Sign> signList = signService.lambdaQuery()
                .eq(Sign::getUserId, loginId)
                .list();
        // 查询考试详情
        List<Exam> examList = this.lambdaQuery()
                .in(Exam::getBusinessId, signList)
                .orderByDesc(Exam::getCreateTime)
                .list();
        // 获取当前时间
        Date now = new Date();
        // 使用Stream API过滤并找到最近的未结束的比赛
        Optional<Exam> nearestUnfinishedExam = examList.stream()
                .filter(exam -> exam.getEndTime().after(now)) // 确保比赛未结束
                .min(Comparator
                        .comparing(exam -> Math.abs(TimeUnit.MILLISECONDS
                                .toMinutes(now.getTime() - exam.getStartTime().getTime()))));
        // 检查是否找到了比赛
        if (!nearestUnfinishedExam.isPresent()) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"没有找到未结束的考试");
        }
        return nearestUnfinishedExam.get();
    }
}




